//
//  UIView+GradientBorder.m
//  健身力量站
//
//  Created by 孔 on 2023/11/14.
//

#import "UIView+GradientBorder.h"
#import <objc/runtime.h>
#import "KSObjcUtil.h"

#ifndef INVALID_POINT
#define INVALID_POINT CGPointMake(-1, -1)
#endif

@implementation UIView (GradientBorder)

+ (void)load{
    ks_exchangeMethod(self, @selector(layoutSubviews), self, @selector(gradient_border_layoutSubviews));
    ks_exchangeMethod(self, @selector(updateConstraints), self, @selector(gradient_border_updateConstraints));
}

- (void)gradient_border_layoutSubviews{
    [self gradient_border_layoutSubviews];
    [self gradient_border_updateFrame];
}

- (void)gradient_border_updateConstraints{
    [self gradient_border_updateConstraints];
    [self gradient_border_updateFrame];
}

- (void)gradient_border_updateFrame{
    if(![self gradient_border_isEnableGradient]){
        return;
    }
    if(!self.borderGradientLayer.superlayer){
        [self.layer insertSublayer:self.borderGradientLayer atIndex:0];
    }
    self.borderGradientLayer.frame = self.bounds;
    [self.borderGradientLayer setNeedsDisplay];
 
}

- (BOOL)gradient_border_isEnableGradient{
    //同时满足四个条件才可以执行渐变
    return self.borderFromColor &&
    self.borderToColor &&
    !CGPointEqualToPoint(self.borderStartPoint, INVALID_POINT) &&
    !CGPointEqualToPoint(self.borderEndPoint, INVALID_POINT);
}

- (void)setBorderFromColor:(UIColor *)borderFromColor{
    objc_setAssociatedObject(self, @selector(borderFromColor), borderFromColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIColor *)borderFromColor{
    return objc_getAssociatedObject(self, _cmd);
}
- (void)setBorderToColor:(UIColor *)borderToColor{
    objc_setAssociatedObject(self, @selector(borderToColor), borderToColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIColor *)borderToColor{
    return objc_getAssociatedObject(self, _cmd);
}
- (void)setBorderStartPoint:(CGPoint)borderStartPoint{
    objc_setAssociatedObject(self, @selector(borderStartPoint), [NSValue valueWithCGPoint:borderStartPoint], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (CGPoint)borderStartPoint{
    id obj = objc_getAssociatedObject(self, _cmd);
    return obj ? [obj CGPointValue]:INVALID_POINT;
}

- (void)setBorderEndPoint:(CGPoint)borderEndPoint{
    objc_setAssociatedObject(self, @selector(borderEndPoint), [NSValue valueWithCGPoint:borderEndPoint], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (CGPoint)borderEndPoint{
    id obj = objc_getAssociatedObject(self, _cmd);
    return obj ? [obj CGPointValue]:INVALID_POINT;
}

- (void)setGradientBorderWidth:(CGFloat)gradientBorderWidth{
    objc_setAssociatedObject(self, @selector(gradientBorderWidth),@(gradientBorderWidth) , OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (CGFloat)gradientBorderWidth{
    id obj = objc_getAssociatedObject(self, _cmd);
    return obj ? [obj floatValue]:CGFLOAT_MIN;
}

- (void)setBorderGradientLayer:(CAGradientLayer *)borderGradientLayer{
    objc_setAssociatedObject(self, @selector(borderGradientLayer), borderGradientLayer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (CAGradientLayer *)borderGradientLayer{
    CAGradientLayer* _gradientLayer = objc_getAssociatedObject(self, _cmd);
    if(!_gradientLayer){
        _gradientLayer = [CAGradientLayer layer];
        _gradientLayer.contentsScale = ks_screenScale();
        [self setBorderGradientLayer:_gradientLayer];
    }
    
    _gradientLayer.locations = @[@0,@1];
    if(!CGPointEqualToPoint(self.borderStartPoint, INVALID_POINT)){
        _gradientLayer.startPoint = self.borderStartPoint;
    }
    if(!CGPointEqualToPoint(self.borderEndPoint, INVALID_POINT)){
        _gradientLayer.endPoint = self.borderEndPoint;
    }
    
    if(self.borderFromColor && self.borderToColor){
        _gradientLayer.colors = @[(__bridge id)self.borderFromColor.CGColor, (__bridge id)self.borderToColor.CGColor];
    }
    
    _gradientLayer.cornerRadius = self.cornerRadius;
    _gradientLayer.maskedCorners = self.maskedCorners;
    
    CAShapeLayer* maskLayer = [CAShapeLayer layer];
    maskLayer.lineWidth = self.gradientBorderWidth;

    maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(self.bounds, self.gradientBorderWidth / 2, self.gradientBorderWidth / 2)
                                           byRoundingCorners:self.maskedCorners
                                                 cornerRadii:CGSizeMake(self.cornerRadius, self.cornerRadius)].CGPath;
    
    maskLayer.fillColor = UIColor.clearColor.CGColor;
    maskLayer.strokeColor = UIColor.blueColor.CGColor;
    _gradientLayer.mask = maskLayer;
    return _gradientLayer;
}

@end
